/* Copyright (c) 2009-2010, Sean A.O. Harney <sharney3@gmail.com> */

#include "omf.h"

void *checked_malloc(size_t size)
{
    return checked_calloc(1, size);
}

void *checked_calloc(size_t nmemb, size_t size)
{
    void *ret = calloc(nmemb, size);
    if (ret == NULL)
	fatal_error_perror("calloc()");

    return ret;
}

char *checked_strdup(const char *s)
{
    char *ret;

    if (s == NULL)
	fatal_error_println("checked_strdup(NULL)");

    ret = strdup(s);
    if (ret == NULL)
	fatal_error_perror("strdup()");

    return ret;

}

void fatal_error()
{
    fatal_error_println("unknown fatal error");
}

//uses errno like perror
void fatal_error_perror(const char *s)
{
    fatal_error_strerror(s, errno);
}

void fatal_error_strerror(const char *s, int errnum)
{
    fatal_error_println("%s : %s", s, strerror(errnum));
}

//adds the \n
void fatal_error_println(const char *fmt, ...)
{
    va_list argp;
    char fixed_fmt[1024];

    snprintf(fixed_fmt, sizeof(fixed_fmt), "FATAL ERROR: %s\n", fmt);

    va_start(argp, fmt);	//fmt is last before the elipsis ...
    vfprintf(stderr, fixed_fmt, argp);
    va_end(argp);

    fflush(stderr);
    exit(EXIT_FAILURE);		/* the fatal part */
}

//adds the \n
void error_println(const char *fmt, ...)
{
    va_list argp;

    va_start(argp, fmt);	//fmt is last before the elipsis ...
    vfprintf(stderr, fmt, argp);
    va_end(argp);

    fprintf(stderr, "\n");
    fflush(stderr);
}
